package com.nettywork.code;


import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class NettyServer {

    public static void main(String args[]){
        //创建2个线程组 bossGroup 专门只处理连接 , 而 workGroup 处理客户端业务的线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workGroup = new NioEventLoopGroup(4);
        try {
        //创建服务端的启动对象 启动引导类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //设置线程组
        serverBootstrap.group(bossGroup, workGroup)
                //使用 NioServerSocketChannel作为服务器的通道实现
            .channel(NioServerSocketChannel.class)
                //初始化服务端连接队列的大小,服务端处理客户端连接是顺序处理,所以同一时间只能处理一个客户端连接
                //多个客户端来的时候,服务端不能处理的请求会放到 服务端初始化的队列里
            .option(ChannelOption.SO_BACKLOG, 1024)
                //创建通道初始化对象,设置初始化参数, 通道的建立   每一个创建的handler业务处理类 放到channelPipeline里
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel){
                    ChannelPipeline channelPipeline = socketChannel.pipeline();
                    //字符串解码器
                    //channelPipeline.addLast(new StringDecoder());
                    //对象解码器
                    //channelPipeline.addLast("decoder",new ObjectDecoder(10240, ClassResolvers.cacheDisabled(null)));
                    channelPipeline.addLast(new NettyServerHandler());
                }
            });
            //sync是等待异步操作执行完毕 之后才继续走下面的代码 就是加上sync这里变成同步操作 不然他默认是异步操作
            ChannelFuture channelFuture = serverBootstrap.bind(6999).sync();
            System.out.println("netty server start:");
            //如果上面默认是异步启动  则下面就需要通过这个监听器回调.
//            channelFuture.addListener(new ChannelFutureListener() {
//                @Override
//                public void operationComplete(ChannelFuture channelFuture) throws Exception {
//                    if(channelFuture.isSuccess()){
//                        System.out.println("监听6999端口成功");
//                    }else{
//                        System.out.println("监听6999端口失败");
//                    }
//                }
//            });
            //等待服务端  监听端口关闭 这里也是异步操作
            //这里设置sync同步操作 是为了等待ChannelFuture关闭处理完毕 之后在关闭服务器端
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }
}
